﻿package {
	import flash.display.*;
	import flash.events.*;
	import flash.net.*;
	import flash.text.*;
	import flash.utils.*;
	import flash.filters.*;
	public class DashBoard extends Sprite {
		private var spre:RegExp = /\s*\,\s*/;
		private var map_data:XMLList;
		private var tipFormat:TextFormat;
		private var tip:TextField;
		private var total:Number;
		private var usa:Sprite;
		//用户层
		private var users:Sprite;
		private var groupMap:Dictionary;
		//饼图
		private var pie:Sprite;
		//颜色组
		private var cList:Array;
		//分数组
		private var sList:Array;
		//xml
		private var xml_url:String = "DashBoard.xml";
		//延时
		private var timeout:Number = 0;
		//最大半径
		private var maxR:Number = 10;
		//最大数
		private var maxN:Number = 10000;
		//曲线图
		//private var curve:Curve;
		private var stageW:Number;
		private var stageH:Number;
		//当前用户对象
		private var nowUser:User;
		public function DashBoard() {
			stage.align = "top";
			stage.scaleMode = "noScale";
			stageW = stage.stageWidth;
			stageH = stage.stageHeight;
			//
			//curve = new Curve();
			//curve.xywh = [0, 500, 800, 100];
			//addChild(curve);
			//
			users = new Sprite();
			addChild(users);
			pie = new Sprite();
			addChild(pie);
			tipFormat = getFormat();
			tip = getTip();
			addChild(tip);
			init();
		}
		private function init():void {
			var url:String = cV("url");
			if (url) {
				xml_url = url;
			}
			//
			var to:Number = parseInt(cV("timeout"));
			if (!isNaN(to)) {
				timeout = to;
			}
			//
			loadData();
		}
		//是否延时刷新
		private function reLoad():void {
			if (timeout) {
				//O.o(timeout);
				setTimeout(loadData, timeout);
			}
		}
		//加载数据
		private function loadData():void {
			var url:String;
			if (timeout) {
				url = xml_url + "?r=" + Math.random();
			} else {
				url = xml_url;
			}
			//O.o(url);
			var loader:URLLoader = new URLLoader();
			loader.load(new URLRequest(url));
			loader.addEventListener(IOErrorEvent.IO_ERROR, errorHd);
			loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, errorHd);
			loader.addEventListener(Event.COMPLETE, completeHd);
		}
		private function errorHd(e:Event):void {
			O.o(e);
			map_data = get_test_data();
			setData();
		}
		private function completeHd(e:Event):void {
			reLoad();
			try {
				map_data = new XMLList(e.target.data);
				setData();
			} catch (e:TypeError) {
				O.o("Error XML Format");
			}
		}
		private function setData():void {
			var time_start:String = map_data.@time_start;
			var time_end:String = map_data.@time_end;
			var lines:String = map_data.@lines;
			var lList:Array = lines.split(spre);
			/*var s:String = "";
			for (var l:int = 0; i< 23*6; i++) {
				s+=680+Math.round(Math.random()*100)+",";
			}*/
			//trace(s);
			var scores:String = map_data.@scores;
			sList = scores.split(spre);
			var colors:String = map_data.@colors;
			cList = colors.split(spre);
			var nums:Number = parseInt(map_data.@nums);
			if (!isNaN(nums)) {
				maxN = nums;
			}
			//显示曲线
			//curve.show(time_start, time_end, lList, sList, cList);
			//取得州
			groupMap = new Dictionary();
			usa = USA;
			usa.filters = gS(0x000000, 0.8);
			stage.addEventListener(MouseEvent.MOUSE_MOVE, moveHd);
			for (var i:int = 0; i<usa.numChildren; i++) {
				var mc:Sprite = usa.getChildAt(i) as Sprite;
				mc.addEventListener(MouseEvent.MOUSE_OVER, overHd);
				mc.addEventListener(MouseEvent.MOUSE_OUT, outHd);
				groupMap[mc.name] = mc;
			}
			//显示用户数据
			showUser();
		}
		//
		private function clearUser():void {
			while (users.numChildren) {
				users.removeChildAt(0);
			}
		}
		private function showUser():void {
			clearUser();
			//
			var userList:XMLList = map_data.l;
			var total:Number = userList.length();
			for (var i:int = 0; i < total; i++) {
				var n:String = userList[i].@n;
				if (n) {
					addUser(userList[i]);
				}
			}
		}
		private function addUser(userData:XML):void {
			var user:User = new User();
			user.filters = gS(0x000000, 1);
			users.addChild(user);
			//
			var c:String = userData.@c;
			if (c) {
				var ux:Number;
				var uy:Number;
				var mc:Sprite = groupMap[c];
				var p:String = userData.@p;
				if (p) {
					var pl:Array = p.split(spre);
					//trace(pl);
					ux = mc.x*usa.scaleX + parseInt(pl[0]) + usa.x;
					uy = mc.y*usa.scaleX + parseInt(pl[1]) + usa.x;
				} else {
					ux = (mc.x + mc.width/2)*usa.scaleX + usa.x;
					uy = (mc.y + mc.height/2)*usa.scaleY + usa.y;
				}
				//
				user.x = ux;
				user.y = uy;
				//
				var n:String = userData.@n;
				var nl:Array = n.split(spre);
				//总数
				var tn:Number = 0;
				//总分数
				var ts:Number = 0;
				for (var i:int = 0; i < nl.length; i++) {
					
					var ni:Number = parseInt(nl[i]);
					nl[i] = ni;
					tn += ni;
					var ms:Number;
					if (i < sList.length - 1){
						ms = parseInt(sList[i]) + (parseInt(sList[i+1]) - parseInt(sList[i]))/2;
					} else {
						ms = parseInt(sList[i]) + (1000 - parseInt(sList[i]))/2;
					}
					ts += ni*ms;
				}
				//保存组
				user.nList = nl;
				user.label = userData.@t + " (Imps:"+tn+")";
				//得出半径
				var ur:Number = maxR * tn/maxN;
				//总平均分
				var ps:Number = Math.round(ts/tn);
				//trace(ps);
				//得出颜色
				var uc:Number = 0;
				for (var j:int = 0; j < sList.length; j++) {
					if (ps >= parseInt(sList[j])) {
						uc = parseInt(cList[j]);
					}
				}
				user.show(ur, uc);
				user.addEventListener(MouseEvent.MOUSE_OVER, uoverHd);
				user.addEventListener(MouseEvent.MOUSE_OUT, uoutHd);
				//user.addEventListener(MouseEvent.CLICK, uclickHd);
			}
		}
		private function showPie(nList:Array):void {
			//trace(nList);
			drawPie(nList);
		}
		private function clearPie():void {
			while (pie.numChildren) {
				pie.removeChildAt(0);
			}
		}
		private function drawPie(nList:Array):void {
			var pieData:Array = new Array();
			//总数
			var tn:Number = 0;
			for (var k:int = 0; k < nList.length; k++) {
				tn += nList[k];
			}
			for (var j:int = 0; j < nList.length; j++) {
				pieData.push([nList[j]/tn, parseInt(cList[j]),nList[j]]);
			}
			//
			clearPie();
			//半径
			var r:Number = 100;
			//饼图背景
			var pieBg:Sprite = new Sprite();
			pieBg.graphics.beginFill(0xf5f5f5, 0.8);
			pieBg.graphics.drawCircle(0, 0, r);
			pieBg.graphics.endFill();
			pie.addChild(pieBg);
			//初始位置
			var degree:Number = 0;
			//饼图扇形
			for (var i:uint = 0; i<pieData.length; i++) {
				var sector:Sprite = new Sprite();
				sector.buttonMode = true;
				pie.addChild(sector);
				var c:Number = pieData[i][1];
				var a:Number = 1;
				var d:Number = Math.ceil(360*pieData[i][0]);
				var n:Number = degree;
				degree += d;
				drawSector(sector, r, c, a, d, n);
				sector.name = "sector__" + i + "__Imps:" + pieData[i][2];
				//sector.addEventListener(MouseEvent.CLICK, clickHd);
				sector.addEventListener(MouseEvent.MOUSE_OVER, soverHd);
				sector.addEventListener(MouseEvent.MOUSE_OUT, soutHd);
				//sector.addEventListener(MouseEvent.MOUSE_MOVE, moveHd);
			}
			pie.filters = gS(0x000000, 0.8);
			//--------------------------------------------------------------
			//nowUser.addChild(pie);
			var xy:Array = getXY(nowUser.x, nowUser.y, r + nowUser.width/2);
			pie.x = xy[0];
			pie.y = xy[1];
		}
		private function getXY(ux:Number, uy:Number, r:Number):Array {
			var ox:Number = stageW/2;
			var oy:Number = stageH/2;
			var degree:Number = Math.atan((uy-oy)/(ux-ox));
			if (ux > ox) {
				r = -r;
			}
			var px:Number = r*Math.cos(degree) + ux;
			var py:Number = r*Math.sin(degree) + uy;
			return [px, py];
		}
		private function drawSector(sector:Sprite, r:Number, c:Number, a:Number, d:Number, n:Number) {
			//
			sector.graphics.beginFill(c, a);
			//边框
			sector.graphics.lineStyle(1, 0xffffff, .5);
			//去边
			sector.graphics.lineTo(r, 0);
			//画弧
			for (var i:Number = 0; i<=d; i++) {
				var bx:Number = r*Math.cos(i*Math.PI/180);
				var by:Number = r*Math.sin(i*Math.PI/180);
				sector.graphics.lineTo(bx, by);
			}
			//回原点
			sector.graphics.lineTo(0, 0);
			sector.graphics.endFill();
			//旋转
			sector.rotation = n;
		}
		//-------------------------------------------------------------------------
		private function uoverHd(e:MouseEvent):void {
			var user:User = e.target as User;
			nowUser = user;
			pie.visible = true;
			//显示pie
			showPie(user.nList);
			//深度
			users.setChildIndex(user, users.numChildren - 1);
			//名称
			tipShow(user.label);
		}
		private function uoutHd(e:MouseEvent):void {
			tipHide();
		}
		private function soverHd(e:MouseEvent):void {
			tipShow(getScore(e.target.name));
		}
		private function soutHd(e:MouseEvent):void {
			tipHide();
		}
		private function moveHd(e:MouseEvent):void {
			if (mouseX + tip.width + 20 >= stage.stageWidth) {
				tip.x = mouseX - tip.width - 20;
			} else {
				tip.x = mouseX + 20;
			}
			tip.y = mouseY;
		}
		private function overHd(e:MouseEvent):void {
			e.target.filters = new Array(new ColorMatrixFilter([1.2, 0, 0, 0, 0, 0, 1.2, 0, 0, 0, 0, 0, 1.2, 0, 0, 0, 0, 0, 1, 0]));
			tipShow(getTitle(e.target.name));
			pie.visible = false;
		}
		private function outHd(e:MouseEvent):void {
			tipHide();
			e.target.filters = new Array(new ColorMatrixFilter([1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0]));
		}
		private function getScore(s:String):String {
			var arr:Array = s.split("__");
			var i:Number = parseInt(arr[1]);
			var end:Number;
			if (i < sList.length - 1) {
				end = parseInt(sList[i+1]) - 1;
			} else {
				end = 1000;
			}
			return sList[i] + "-" + end.toString() + " ("+arr[2]+")";
		}
		private function getTitle(c:String):String {
			var xl:XMLList = map_data.l.(@c == c);
			var l:int = xl.length();
			if (l > 1) {
				return xl[0].@t;
			} else {
				return xl.@t;
			}
		}
		//
		private function tipShow(msg:String):void {
			tip.text = msg;
			tip.setTextFormat(tipFormat);
			tip.visible = true;
		}
		private function tipHide():void {
			tip.visible = false;
			tip.text = "";
		}
		//格式
		private function getFormat():TextFormat {
			var tf:TextFormat = new TextFormat();
			tf.font = "Arial";
			tf.size = 12;
			tf.bold = true;
			tf.leftMargin = 10;
			tf.rightMargin = 10;
			return tf;
		}
		//提示
		private function getTip():TextField {
			var tip:TextField = new TextField();
			tip.selectable = false;
			tip.mouseEnabled = false;
			tip.autoSize = "left";
			tip.background = true;
			tip.backgroundColor = 0xffffff;
			tip.border = true;
			tip.borderColor = 0xeeeeee;
			tip.visible = false;
			tip.filters = gS(0x000000, 1);
			return tip;
		}
		//滤镜
		public function gS(c:Number,a:Number):Array {
			return new Array(new DropShadowFilter(1,45,c,a,4,4,1,1));
		}
		//读取传入参数
		public function cV(str:String):String {
			return this.root.loaderInfo.parameters[str];
		}
		//--------------------------------------------------------------------------
		private function get_test_data():XMLList {
			var test_xml:XML = <l 
time_start="June 1,2008" 
time_end="June 23,2008" 
lines="706,703,690,667,672,728,666,664,710,731,707,724,655,731,673,689,734,688,664,676,690,666,655,684,705,744,699,743,691,663,695,706,732,709,706,714,729,660,676,654,690,692,681,723,712,715,688,736,707,722,689,713,714,742,698,708,680,745,686,693,746,654,725,734,744,707,668,662,701,682,708,742,687,710,653,673,740,654,663,742,720,675,661,694,699,727,699,727,676,659,724,651,743,717,674,669,665,665,652,697,651,663,693,679,748,723,731,721,745,738,675,712,670,674,656" 
scores="600,650,700,750,800" 
colors="0xff0000,0xffc0cb,0xffff00,0x0000ff,0x00ff00"
nums="10000"
>
  <l c="AL" p="" n="" t="Alabama" />
  <l c="AK" p="70,30" n="" t="Alaska" />
  <l c="AZ" p="" n="" t="Arizona" />
  <l c="AZ" p="42,68" n="201,1123,1314,2205,1722" t="Phoenix" />

  <l c="AR" p="" n="" t="Arkansas" />
  
  <l c="CA" p="" n="" t="California" />

  <l c="CA" p="15,80" n="401,1123,315,3206,4722" t="San Francisco" />
  <l c="CA" p="18,90" n="208,127,2312,3203,1727" t="San Jose" />
  <l c="CA" p="70,160" n="603,1122,1314,3205,722" t="Los Angeles" />
  <l c="CA" p="78,188" n="202,124,1315,1206,722" t="San Diego" />
  
  <l c="CO" p="" n="" t="Colorado" />
  <l c="CT" p="" n="" t="Connecticut" />
  <l c="DE" p="" n="" t="Delaware" />
  <l c="FL" p="100,45" n="1002,1124,2351,1206,722" t="Florida" />
  <l c="GA" p="" n="" t="Georgia" />
  <l c="HI" p="" n="" t="Hawaii" />
  <l c="ID" p="" n="" t="Idaho" />
  <l c="IL" p="" n="" t="Illinois" />
  <l c="IL" p="50,12" n="2902,1204,1315,1207,722" t="Chicago" />

  <l c="IN" p="" n="" t="Indiana" />
  <l c="IA" p="" n="" t="Iowa" />
  <l c="KS" p="" n="" t="Kansas" />
  <l c="KY" p="" n="" t="Kentucky" />
  <l c="LA" p="" n="" t="Louisiana" />
  <l c="ME" p="" n="" t="Maine" />
  <l c="MD" p="" n="" t="Maryland" />
  <l c="MD" p="" n="1005,242,2344,1445,2068" t="Washington" />

  <l c="MA" p="" n="" t="Massachusetts" />
  <l c="MI" p="" n="" t="Michigan" />
  <l c="MN" p="" n="" t="Minnesota" />
  <l c="MS" p="" n="" t="Mississippi" />
  <l c="MO" p="" n="" t="Missouri" />
  <l c="MT" p="" n="" t="Montana" />
  <l c="NE" p="" n="" t="Nebraska" />
  <l c="NV" p="" n="" t="Nevada" />
  <l c="NH" p="" n="" t="New hampshire" />
  <l c="NJ" p="" n="" t="New jersey" />
  <l c="NM" p="" n="" t="New mexico" />

  <l c="NY" p="90,68" n="306,402,684,3402,2506" t="New york" />

  <l c="NC" p="" n="1002,1244,345,446,1082" t="North carolina" />
  <l c="ND" p="" n="" t="North dakota" />
  <l c="OH" p="" n="" t="Ohio" />
  <l c="OK" p="" n="" t="Oklahoma" />
  <l c="OR" p="" n="" t="Oregon" />
  <l c="PA" p="" n="" t="Pennsylvania" />
  <l c="RL" p="" n="" t="Rhode island" />
  <l c="SC" p="" n="" t="South carolina" />
  <l c="SD" p="" n="" t="South dakota" />
  <l c="TN" p="" n="" t="Tennessee" />

  <l c="TX" p="" n="" t="Texas" />
  <l c="TX" p="165,125" n="1002,1244,2341,1445,1205" t="Houston" />
  <l c="TX" p="120,130" n="2003,1243,2342,444,202" t="San Antonio" />
  <l c="TX" p="140,80" n="1004,122,23,143,2032" t="Dallas" />
  <l c="TX" p="130,120" n="1002,804,1354,1442,902" t="Austin" />
  

  <l c="UT" p="" n="" t="Utah" />
  <l c="VT" p="" n="" t="Vermont" />
  <l c="VA" p="" n="" t="Virginia" />
  <l c="WA" p="" n="" t="Washington" />
  <l c="WV" p="" n="" t="West virginia" />
  <l c="WI" p="" n="" t="Wisconsin" />
  <l c="WY" p="" n="" t="Wyoming" />
</l>;
			return new XMLList(test_xml.toXMLString());
			
		}
	}
}